
const Util = require('Util');
let RoadBlockPool = require('GameObjectPool').RoadBlock;
let RoadBlockEffectPool = require('GameObjectPool').RoadBlockEffect;
let ItemPool = require('GameObjectPool').Item;

const RoadBlock = require('RoadBlock');


let RoadBlockFactory = function () {};

RoadBlockFactory.prototype = {
    constructor: RoadBlockFactory,

    init(callback) {
        let tasks = [];

        let blockPrefabMap = {};
        for (let [type, prefabName] of game.RoadBlock) {
            tasks.push((done) => {
                Util.loadPrefab('prefab/'+ prefabName, (prefabNode) => {
                    blockPrefabMap[type] = prefabNode;

                    done();
                })
            });
        }

        let itemPrefabMap = {};
        for (let [type, prefabName] of game.Item) {
            tasks.push((done) => {
                Util.loadPrefab('prefab/'+ prefabName, (prefabNode) => {
                    itemPrefabMap[type] = prefabNode;

                    done();
                })
            });
        }

        tasks.push((done) => {
            Util.loadPrefab('prefab/'+ game.Effect.ROADBLOCK_REMOVED, (prefabNode) => {
                RoadBlockEffectPool.setPrefabNode(prefabNode);

                done();
            });
        });

        Util.series(tasks, () => {
            RoadBlockPool.setPrefabNodeMap(blockPrefabMap);
            ItemPool.setPrefabNodeMap(itemPrefabMap);

            // Pre-reserve
            let reserveNumMap = {
                [RoadBlock.Type.SMALL]: 30,
                [RoadBlock.Type.MEDIUM]: 30,
                [RoadBlock.Type.BIG]: 4
            };
            for (let i = 0, types = Object.keys(reserveNumMap), type; type = types[i++];) {
                let num = reserveNumMap[type];
                for (let j = 0; j < num; j++) {
                    RoadBlockPool.put( cc.instantiate(RoadBlockPool.prefabNodeMap[type]) );
                }
            }

            for (let i = 0; i < 30; i++) {
                RoadBlockEffectPool.put( cc.instantiate(RoadBlockEffectPool.prefabNode) );
            }

            for (let i = 0, nodes = Object.values(ItemPool.prefabNodeMap), node; node = nodes[i++];) {
                for (let j = 0; j < 3; j++) {
                    ItemPool.put( cc.instantiate(node) );
                }
            }


            callback();
        });
    },

    createBlock(type, hpType, callback) {
        let blockNode = RoadBlockPool.get(type);
        let block = blockNode.getComponent('RoadBlock');
        block.hpType = hpType;

        callback(block);
    },
    createBlockEffect() {
        let blockEffectNode = RoadBlockEffectPool.get();
        return blockEffectNode.getComponent('RoadBlockEffect');
    },

    getBlockSize(type) {
        let prefabNode = RoadBlockPool.prefabNodeMap[type];
        return prefabNode.getContentSize();
    },

    createItem(type, callback) {
        let itemNode = ItemPool.get(type);
        let item = itemNode.getComponent('Item');

        callback(item);
    },

    getItemSize(type) {
        let prefabNode = ItemPool.prefabNodeMap[type];
        return prefabNode.getContentSize();
    }
};


module.exports = new RoadBlockFactory();